﻿#ifndef __AVOID_H_CONTROL_MATRIX_H__
#define __AVOID_H_CONTROL_MATRIX_H__
#include <cmath>
#include <windows.h>
#include <gdiplus.h>

namespace swui
{
	class ctlMatrix
	{
	public:
		ctlMatrix() {}
		ctlMatrix(const ctlMatrix& v)
		{
			float f[6];
			v._matrix_m.GetElements(f);
			_matrix_m.SetElements(f[0], f[1], f[2], f[3], f[4], f[5]);
		}
	public:
		ctlMatrix& rotate(float deg)
		{
			_matrix_m.Rotate(deg);
			return *this;
		}
		ctlMatrix& scale(float x, float y)
		{
			_matrix_m.Scale(x, y);
			return *this;
		}
		ctlMatrix& translate(float x, float y)
		{
			_matrix_m.Translate(x, y);
			return *this;
		}
		ctlMatrix& resetMatrix()
		{
			_matrix_m.Reset();
			return *this;
		}
		ctlMatrix& offset(float x, float y)
		{
			float f[6];
			_matrix_m.GetElements(f);
			_matrix_m.SetElements(f[0], f[1], f[2], f[3], f[4] + x, f[5] + y);
			return *this;
		}
		ctlMatrix& shear(float x, float y)
		{
			_matrix_m.Shear(x, y);
			return *this;
		}
		ctlRect transformRect(ctlRect rect)
		{
			using namespace Gdiplus;
			Point pt[4] = { Point(0, 0), Point(rect.getWidth(), 0), 
				Point(0, rect.getHeight()), Point(rect.getWidth(), rect.getHeight()) };
			getNativeMatrix()->TransformPoints(pt, 4);
			int maxx = pt[0].X, maxy = pt[0].Y, minx = pt[0].X, miny = pt[0].Y;
			for(int i = 1; i != 4; ++i)
			{
				if(pt[i].X > maxx) maxx = pt[i].X;
				if(pt[i].Y > maxy) maxy = pt[i].Y;
				if(pt[i].X < minx) minx = pt[i].X;
				if(pt[i].Y < miny) miny = pt[i].Y;
			}
			return ctlRect(minx, miny, maxx - minx, maxy - miny);
		}

		Gdiplus::Matrix* getNativeMatrix()
		{
			return &_matrix_m;
		}
	public:
		Gdiplus::Matrix _matrix_m;
	};
}

#endif